#include "Progression.h"

#include "Joueur.h"

#include "Classe.h"

#include "DemanderNbr.h"
#include "AugPourcent.h"

#include <QtGui/QVBoxLayout>
#include <QtGui/QHBoxLayout>
#include <QtGui/QSpinBox>
#include <QtGui/QLabel>
#include <QtGui/QGroupBox>
#include <QtGui/QPushButton>

#include <QtGui/QApplication>

#include <boost/assign/list_of.hpp>

using namespace boost::assign;

/** Constructeur par défaut.
 * Initialise les différents widgets affichés.
 *
 * @param j pointeur sur le PJ que l'on veut faire évoluer.
 * @param parent pointeur sur le widget parent (orphelin par défaut).
 */
Progression::Progression(Joueur *j, QWidget *parent)
  : BaseUI( QString::fromUtf8("Progression"), parent )
{
  joueur = j;

  spin1 = new QSpinBox( this );
  spin2 = new QSpinBox( this );

  spin1 -> setMinimum( 0 );
  spin1 -> setMaximum( 1000000 );
  spin2 -> setMinimum( 0 );
  spin2 -> setMaximum( 30 );

  leg1 = new QLabel( trUtf8("Nombre de XP gagnés"), this );
  leg2 = new QLabel( trUtf8("Nombre de PP obtenus"), this );

  QGroupBox *groupe1 = new QGroupBox( trUtf8("Expérience"), this );
  QGroupBox *groupe2 = new QGroupBox( trUtf8("Point de personnages"), this );

  boutons.push_back( new QPushButton( trUtf8("&Quitter"), this ) );
  boutons.back() -> setToolTip( trUtf8("Quitter le programme") );
  connect( boutons.back(), SIGNAL( clicked() ), this, SLOT( annuler() ) );
  boutons.push_back( new QPushButton( trUtf8("&OK"), this ) );
  boutons.back() -> setToolTip( trUtf8("Accepter et continuer") );
  connect( boutons.back() , SIGNAL( clicked() ), this, SLOT( fermer() ) );

  QVBoxLayout *boxLayout1, *boxLayout2;

  boxLayout1 = new QVBoxLayout();
  boxLayout2 = new QVBoxLayout();

  boxLayout1 -> addWidget(leg1);
  boxLayout1 -> addWidget(spin1);
  groupe1 -> setLayout(boxLayout1);

  boxLayout2 -> addWidget(leg2);
  boxLayout2 -> addWidget(spin2);
  groupe2 -> setLayout(boxLayout2);

  fenetreLayout -> addWidget(groupe1);
  fenetreLayout -> addWidget(groupe2);

  setFenetreLayout();
}

/**
 * Destructeur, ne fait rien de spécial
 */
Progression::~Progression()
{}

/**
 * Permet de récupérer le nombre de points d'expériences et de points
 * de personnage gagnés.
 *
 * Si le choix est validé, on ajoute alors les XP et PP. On regarde si
 * le PJ passe un niveau, dans le cas positif, on va demander à
 * l'utilisateur d'entrer le nombre de PV qu'il a obtenu.
 *
 * @return StatusCode \e true si choix validé \e false sinon, le
 * nombre de xp est donnés par valeur(), le nombre de pp par valeur(1).
 */
StatusCode Progression::pointsGagnes()
{
  /*Debug::*/empileNiveau( &interne );
  func() << "Progression::pointsGagnes -> début" << endmsg;

  this -> show();

  qApp -> exec();

  if ( OK )
    {
      joueur -> ajouterPP( spin2 -> value() );

      int ajustement( 0 );

      StatusCode niv( joueur -> ajouterXP( spin1 -> value() ) );
      if ( niv )
	{
	  info() << "Le personnage passe un niveau" << endmsg;

	  DemanderNbr PVs( "Nombre de PV gagnés",
			   "Entrer le nombre de PV gagnés, sans éventuel\nbonus de Constitution.",
			   1, 12, this);

	  StatusCode sc( PVs.Nbr() );

	  if ( sc )
	    {
	      bool OK;
	      QString qVal( joueur -> ajustementPV() . c_str() );

	      qVal.remove( QChar('$') );

	      ajustement =  qVal.toInt( &OK, 10 );

	      if ( !OK )
		{
		  error() << "Impossible de convertir " << qVal.toStdString()
			  << endmsg;
		  ajustement = 0;
		}

	      debug() << "Gagné " << sc.valeur() << " + "  << ajustement
		      <<  " PV" << endmsg;
		
	    }
	  else
	    error() << "Erreur : " << sc.valeur() << endmsg;

	  Classe *mClasse;

 	  if ( joueur -> typeMulti() == 1 )
	    mClasse = joueur -> classePtr( niv.valeur() );
	  else
	    mClasse = joueur -> classePtr();

	  mClasse -> augmenterPV( sc.valeur() + ajustement );

	  AugPourcent augPourcent( mClasse, true, this );

	  augPourcent . exec();
	}
    }

  func() << "Progression::pointsGagnes -> fin" << endmsg;
  /*Debug::*/depileNiveau();

  vector< int > vec;

  return StatusCode( OK, vec = list_of( spin1 -> value() )( spin2 -> value() ) );
}
